package br.com.ds3.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;

import br.com.ds3.model.GenericModel;
import br.com.ds3.util.HibernateUtil;

/**
 *
 * @author marcio
 * @param <T>
 */
public abstract class GenericDAO<T extends GenericModel> {
    private final Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    
    public abstract Class<T> getModelClass();
    
    public Session getSession() {
        return session;
    }
    
    public void save(T model) {
        getSession().saveOrUpdate(model);
    }
    
    public void delete(T model) {
        getSession().delete(model);
    }
    
    @SuppressWarnings("unchecked")
	public T get(Long id) {
        return (T) getSession().get(getModelClass(), id);
    }
    
    @SuppressWarnings("unchecked")
	public List<T> list() {
        Criteria criteria = getSession().createCriteria(getModelClass());
        return criteria.list();
    }
    
    @SuppressWarnings("unchecked")
	public List<T> executaCriteria(Criteria criteria, Long pagina, Long tamanho) {
		if (pagina != null) {
			criteria.setFirstResult((pagina.intValue() - 1) * tamanho.intValue());
			criteria.setMaxResults(tamanho.intValue());
		}
		
		return criteria.list();
	}
    
    public Long countCriteria(Criteria criteria) {
    	criteria.setProjection(Projections.rowCount());
    	return (Long) criteria.uniqueResult();
    }
    
    protected Long countPaginas(Long quantidadeRegistros, Long tamanhoPagina) {    	
    	Long paginas = quantidadeRegistros / tamanhoPagina;
    	
    	Long resto = quantidadeRegistros - (paginas * tamanhoPagina);
    	
    	if (resto > 0) {
    		paginas++;
    	}
    	
    	return paginas;
    }
}
